﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Collections;
using System.Data.Common;
using System.Data.SqlClient;

using Coolite.Ext.Web;
using Sagacity.Entity.Query;
using Sagacity.NC.Business.SysMange;
using Sagacity.NC.Entity.SysEntity;

namespace Sagacity.NC.Web.FormForm
{
    /// <summary>
    /// 表单助手类
    /// </summary>
    public class FormHelper
    {
        #region 属性设置
        /// <summary>
        /// pubulic类型成员变量主要用于外部类的访问
        /// </summary>
        public Business.SysMange.Common mCommon = new Business.SysMange.Common();
        public ShowPlan showPlan = ShowPlan.OneRowTwoColumn;
        public int _colFilterKey = 0;
        public string _colFilterIdentify = "";
        public List<Sagacity.Entity.Query.ParameterInfo> _params = new List<ParameterInfo>();
        public int _filterModelId = 0;
        public Hashtable hasFieldSource = new Hashtable();

        /// <summary>
        /// 字段默认值
        /// </summary>
        public Hashtable hasFieldDefault = new Hashtable();
        public bool showForm = true;
        public bool showDetailsColumn = true;

        public FormUser _currentUser;

        /// <summary>
        /// 默认分组字段背景颜色
        /// </summary>
        public string GroupFieldColor = "#ffffff";

        private Sagacity.Entity.Build.ResourceInfo _resourceInfo = new Sagacity.Entity.Build.ResourceInfo();

        private DataRow mRow = null;

        public Sagacity.Entity.Build.RoleInfo role = null;
        public Sagacity.Build.Application.Resource _resource = new Sagacity.Build.Application.Resource();
        private List<FieldDatasourceParamInfo> _fieldParams = new List<FieldDatasourceParamInfo>();

        private const string blankText = "此项为必填或必选项！";

        #endregion

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="resourceId">资源编号</param>
        public FormHelper() 
        { 
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="resourceId">资源编号</param>
        /// <param name="FilterKey"></param>
        /// <param name="FilterIdentify"></param>
        /// <param name="paramters"></param>
        public FormHelper(int FilterKey, string FilterIdentify, List<Sagacity.Entity.Query.ParameterInfo> paramters)
        {
            _colFilterKey = FilterKey;
            _colFilterIdentify = FilterIdentify;
            _params = paramters;
        }

        /// <summary>
        /// 设置窗体表单显示
        /// </summary>
        public void SetGridEditInfo(Sagacity.Entity.Build.RoleInfo loginRole, int resourceId,
            GridPanel handleObject, Store handleSource,
            List<Sagacity.Entity.Query.FilterInfo> filters, string tableKey,
            Coolite.Ext.Web.Window winForm, ControlCollection container,
            out string fieldXML, bool reset, System.Web.UI.WebControls.Panel otherContent)
        {
            role = loginRole;
            List<Sagacity.Entity.Build.QueryFieldInfo> fields = null;

            DataTable orders = GetOrdersInfo(loginRole, resourceId, out fields, filters);

            orders = Business.SysMange.Common.GetSortData(resourceId, orders, fields);
            //绑定数据源
            this.SetStore(fields, handleSource, tableKey);
            handleSource.DataSource = orders;
            handleSource.DataBind();

            #region 重新构建表单
            fieldXML = "";
            if (reset == true)
            {
                GridFilters gridfilters = handleObject.FindControl("GridFilters1") as GridFilters;


                //获取字段信息，使用XML格式存储
                fieldXML = GetResourceFieldXML(fields, tableKey, null);

                RowNumbererColumn rownum = new RowNumbererColumn();
                handleObject.ColumnModel.Columns.Add(rownum);

                //显示表单样式                

                List<Sagacity.Entity.Build.QueryFieldInfo> gFields = fields.FindAll(o => o.IsHidden == false);
                if (showForm)
                    this.ShowForm(gFields.FindAll(o => o.FieldControlType.Trim() != ""), winForm, container, otherContent);
                //绑定GridPanel列
                foreach (Sagacity.Entity.Build.QueryFieldInfo s in gFields)
                {
                    Column column = new Column();
                    column.Header = s.FieldCaption;

                    column.DataIndex = HasHelpCaption(s) ? "CAPTION_" + s.FieldName.ToUpper() : s.FieldName.ToUpper();
                    column.ColumnID = s.FieldName.ToUpper();
                    column.Renderer.Fn = "Form$FloatText";
                    column.Fixed = s.IsFixed;
                    column.Width = s.FieldWidth;
                    column.Tooltip = s.FieldCaption;

                    if (s.FieldControlType != null && s.FieldControlType.Equals("Button"))
                        column.Renderer.Fn = "Form$ButtonRender";

                    if (s.FieldStyle != 0)
                        column.Renderer.Fn = "From$LinkRender";

                    s.FieldControlType = string.IsNullOrEmpty(s.FieldControlType) || s.FieldControlType == "Label" ? "Text" : s.FieldControlType;

                     this.SetColumnFilter(s, gridfilters, column);

                    handleObject.ColumnModel.Columns.Add(column);
                }

                if (showDetailsColumn)
                {
                    Column linkColumn = new Column();
                    linkColumn.Renderer.Fn = "Form$DetailsRender";
                    linkColumn.ColumnID = "Details";
                    linkColumn.DataIndex = fields[0].FieldName;
                    linkColumn.Width = 35;
                    handleObject.ColumnModel.Columns.Add(linkColumn);
                }
            }


            #endregion
        }

        /// <summary>
        /// 获取资源数据的排序方法
        /// </summary>
        /// <param name="resourceId"></param>
        /// <param name="dt"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public static DataTable GetSortData(int resourceId, DataTable dt, List<Sagacity.Entity.Build.QueryFieldInfo> fields) 
        {
            List<ResourceSortInfo> sorts = new Business.SysMange.Common().GetResourceSortInfoByRID(resourceId);
            string sort = string.Empty;

            if (sorts != null && sorts.Count == 0)
                return dt;

            foreach (ResourceSortInfo s in sorts) 
            {
                Sagacity.Entity.Build.QueryFieldInfo f = fields.Find(o => o.Id == s.ResourceFieldId);
                if (f != null) 
                {
                    sort += (f.FieldName + " " + s.SortType + ",");
                }
            }

            sort = sort.Remove(sort.LastIndexOf(','),1);
            dt.DefaultView.Sort = sort;

            return dt;
        }

        /// <summary>
        /// 设置页面表单显示
        /// </summary>
        public void SetFormShow(Sagacity.Entity.Build.RoleInfo loginRole, int resourceId,
            List<Sagacity.Entity.Query.FilterInfo> filters, string tableKey, ControlCollection container,
            out string fieldXML, bool reset, System.Web.UI.WebControls.Panel otherContent)
        {
            fieldXML = "";
            //try
            //{
                role = loginRole;
                List<Sagacity.Entity.Build.QueryFieldInfo> fields = null;
                DataTable dt = GetOrdersInfo(loginRole, resourceId, out fields, filters);
                mRow = dt.Rows.Count == 0 ? null : dt.Rows[0];


                //重新构建表单
                if (reset == true)
                {
                    System.Web.UI.HtmlControls.HtmlTable table = new System.Web.UI.HtmlControls.HtmlTable();
                    SetTableBody(table, container, fields.FindAll(o => o.IsHidden == false && o.FieldControlType.Trim() != ""), otherContent);
                    fieldXML = GetResourceFieldXML(fields, tableKey, mRow);
                    container.Add(table);
                }
            //}
            //catch
            //{
            //}
        }

        /// <summary>
        /// 获取资源数据
        /// </summary>
        public DataTable GetOrdersInfo(Sagacity.Entity.Build.RoleInfo roleInfo, int resourceId,
                out List<Sagacity.Entity.Build.QueryFieldInfo> listFields, List<Sagacity.Entity.Query.FilterInfo> filters)
        {
            _resourceInfo = _resource.GetResrouse(resourceId);

            _fieldParams = _resourceInfo.FieldParams;

            _resourceInfo.Model.Filters.Clear();
            _resourceInfo.Model.Filters = filters;

            _resourceInfo.Model.Parameters = _params;

            listFields = _resourceInfo.Fields;
            DataTable dt = (new Sagacity.Build.Role()).GetFormRightResourceDataTable(_resourceInfo, roleInfo);

            for (int i = 0; i < dt.Columns.Count; i++)
            {
                dt.Columns[i].ColumnName = dt.Columns[i].ColumnName.ToUpper();
            }

            return dt;
        }

        /// <summary>
        /// 取得关联字段数据信息
        /// </summary>
        /// <param name="controlType">控件类型</param>
        /// <param name="fieldId">字段编号</param>
        /// <returns></returns>
        public string GetFieldAssoDataInfo(string controlType,int fieldId,string paramName,string paramValue)
        {
            string jsonData = string.Empty;
            Sagacity.Entity.Build.QueryFieldInfo fieldInfo = _resource.GetResourceFieldInfo(fieldId);
            fieldInfo.ReplaceFieldParamter(paramName, paramValue);
            DataTable dt = mCommon.GetSQLResult(fieldInfo.FieldDataSource,null);
            if (controlType == "Combox")
            {
                jsonData = Business.SysMange.Common.DataTableToJson(dt);
            }
            else //树形控件
            {
                System.Data.DataView view = new System.Data.DataView(dt);
                view.Sort = "parentId";
                dt = view.ToTable();
                if (dt.Rows.Count == 0)
                    return "[]";
                string parentId = dt.Rows[0]["parentId"].ToString();

                jsonData = GetChildRenJson(dt,parentId);
            }
            return jsonData + string.Format("$\"controlType\":\"{0}\",\"paramName\":\"{1}\",\"paramValue\":\"{2}\",\"fieldName\":\"{3}\"", controlType, paramName, paramValue, fieldInfo.FieldName);
        }

        public static string GetChildRenJson(DataTable dt, string parentId) 
        {
            DataRow[] rows = dt.Select("parentId=" + parentId);
            bool hasDataTypeCol = dt.Columns.Contains("DataType");
            string json = "[";
            
            foreach (DataRow r in rows)
            {
                string childrenjson = GetChildRenJson(dt, r["Id"].ToString());
                string dataType = hasDataTypeCol ? r["DataType"].ToString() : "1";

                json += "{'ID':'" + r["id"].ToString() + "','CAPTION':'" + r["caption"].ToString() + "','CHILDREN':" + childrenjson + ",'ISDATA':'"+dataType+"'},";
            }

            json += "]";
            return json.Length > 2 ? json.Remove(json.LastIndexOf(','),1): "[]";
        }

        #region 配置表单显示方法
        /// <summary>
        /// 设置列过滤
        /// </summary>
        protected void SetColumnFilter(Sagacity.Entity.Build.QueryFieldInfo s, GridFilters gridfilters, Column column)
        {
            GridFilter filter = null;
            if (showForm == false && s.FieldControlType == "Combox")
                s.FieldControlType = "Text";

            switch (s.FieldControlType)
            {
                case "Month":
                case "Text":
                    filter = new StringFilter();
                    break;
                case "TextArea":
                    filter = new StringFilter();
                    break;
                case "DateTime":
                    DateFilter dfilter = new DateFilter();
                    dfilter.DatePickerOptions.TodayText = "今天";
                    dfilter.BeforeText = "之前";
                    dfilter.AfterText = "之后";
                    dfilter.OnText = "此时";
                    column.Renderer.Fn = "Ext.util.Format.dateRenderer('Y-m-d')";
                    filter = dfilter;
                    break; 
                case "Numeric":
                    filter = new NumericFilter();
                    break;
                case "Combox":
                    DataRowCollection rows = (hasFieldSource[s.FieldName] as DataTable).Rows;
                    if (rows.Count == 0)
                        break;
                    ListFilter lfilter = new ListFilter();                    
                    string[] filters = new string[rows.Count];
                    for (int i = 0; i < rows.Count; i++)
                    {
                        filters[i] = rows[i]["Caption"].ToString();
                    }
                    lfilter.Options = filters;
                    filter = lfilter;
                    break;
                default:
                    filter = new StringFilter();
                    break;
            }
            if (filter == null)
                return;

            filter.DataIndex = HasHelpCaption(s) ? "CAPTION_" + s.FieldName.ToUpper() : s.FieldName.ToUpper();
            gridfilters.Filters.Add(filter);
        }

        public bool HasHelpCaption(Sagacity.Entity.Build.QueryFieldInfo qf)
        {
            return qf.FieldDataSource != null && !string.IsNullOrEmpty(qf.FieldDataSource.Trim()) && qf.FieldControlType != "Button" && qf.FieldControlType != "Formula" || qf.FieldControlType.IndexOf("Selector") > -1;
        }

        /// <summary>
        /// 设置Store主键列和绑定字段
        /// </summary>
        public void SetStore(List<Sagacity.Entity.Build.QueryFieldInfo> fields, Coolite.Ext.Web.Store store, string tableKey)
        {
            JsonReader reader = new JsonReader();
            reader.ReaderID = tableKey;
            foreach (Sagacity.Entity.Build.QueryFieldInfo q in fields)
            {
                RecordField field = new RecordField();
                field.Name = q.FieldName.ToUpper();
                if (q.FieldControlType == "DateTime")
                {
                    field.Type = RecordFieldType.Date;
                    field.DateFormat = "Y-m-d";
                }

                if (HasHelpCaption(q))
                {
                    RecordField captionField = new RecordField();
                    captionField.Name = "CAPTION_" + q.FieldName.ToUpper();
                    reader.Fields.Add(captionField);
                }

                reader.Fields.Add(field);
            }
            store.Reader.Add(reader);
        }

        /// <summary>
        /// 设置WinForm窗体显示
        /// </summary>
        protected void ShowForm(List<Sagacity.Entity.Build.QueryFieldInfo> fields, Coolite.Ext.Web.Window winForm,
             ControlCollection container, System.Web.UI.WebControls.Panel otherContent)
        {
            if (fields.Count == 0)
                return;

            fields = fields.FindAll(o => o.FieldControlType != "Button");
            System.Web.UI.HtmlControls.HtmlTable table = new System.Web.UI.HtmlControls.HtmlTable();
            table.Width = "100%";

            int rowCount = SetTableBody(table, container, fields, otherContent);

            HtmlTableRow rown = new HtmlTableRow();
            rown.Height = "25";
            HtmlTableCell cell2n = new HtmlTableCell();
            cell2n.Width = "50%";
            cell2n.Align = "right";
            cell2n.ColSpan = 2;
            HtmlTableCell cell4n = new HtmlTableCell();
            cell4n.Width = "50%";
            cell4n.Align = "left";
            cell4n.ColSpan = 2;
            rown.Cells.Add(cell2n);
            rown.Cells.Add(cell4n);
            table.Rows.Add(rown);

            Coolite.Ext.Web.Button btnSub = new Coolite.Ext.Web.Button();
            btnSub.ID = "btnSaveDeteil";
            btnSub.Text = "保 存";
            btnSub.Icon = Coolite.Ext.Web.Icon.Accept;
            btnSub.Listeners.Click.Handler = "javascript:saveFormData();";
            cell2n.Controls.Add(btnSub);

            Coolite.Ext.Web.Button btnAdd = new Coolite.Ext.Web.Button();
            btnAdd.ID = "btnAddDetail";
            btnAdd.Text = "取 消";
            btnAdd.Icon = Icon.Decline;
            btnAdd.Listeners.Click.Handler = "javascript:hidWinForm();";
            cell4n.Controls.Add(btnAdd);

            winForm.Height = showPlan == ShowPlan.GroupStyle ? 43 + (rowCount + 1) * 25 : 43 + (rowCount + 1) * 40;
            container.Add(table);
        }

        /// <summary>
        /// 设置表单样式以及控件,并返回控件中的行数
        /// </summary>
        public int SetTableBody(System.Web.UI.HtmlControls.HtmlTable table, ControlCollection container,
            List<Sagacity.Entity.Build.QueryFieldInfo> fields, System.Web.UI.WebControls.Panel otherContent)
        {
            table.ID = "StyleGrid";
            table.Style.Add("width", "100%");
            table.Style.Add("position", "absolute");

            int rowCount = 0;

            switch (showPlan)
            {
                case ShowPlan.OneRowOneColumn:
                    #region 一行一列
                    if (showPlan == ShowPlan.OneRowOneColumn)

                        for (int i = 0; i < fields.Count; i++)
                        {
                            HtmlTableRow row = new HtmlTableRow();
                            row.Height = "40";
                            HtmlTableCell cell1 = new HtmlTableCell();
                            cell1.Width = "20%";
                            HtmlTableCell cell2 = new HtmlTableCell();
                            cell2.Width = "80%";
                            cell1.Attributes.Add("class", "list-item");
                            cell2.Attributes.Add("class", "list-item");
                            row.Cells.Add(cell1);
                            row.Cells.Add(cell2);
                            table.Rows.Add(row);
                        }

                    for (int i = 0; i < fields.Count; i++)
                    {
                        table.Rows[i].Cells[0].InnerText = fields[i].FieldCaption + ":";
                        table.Rows[i].Cells[1].Controls.Add(GetControl(fields[i], otherContent));
                    }
                    #endregion
                    break;
                case ShowPlan.OneRowTwoColumn:
                    #region 一行两列

                    //获取当前布局表单应该生成的行数
                    bool isOdd = false;
                    isOdd = fields.Count % 2 == 0;
                    rowCount = fields.Count % 2 == 0 ? fields.Count / 2 : fields.Count / 2 + 1;

                    for (int i = 0; i < rowCount; i++)
                    {
                        HtmlTableRow row = new HtmlTableRow();
                        row.Height = "40";
                        HtmlTableCell cell1 = new HtmlTableCell();
                        cell1.Width = "17%";
                        HtmlTableCell cell2 = new HtmlTableCell();
                        cell2.Width = "33%";
                        HtmlTableCell cell3 = new HtmlTableCell();
                        cell3.Width = "17%";
                        HtmlTableCell cell4 = new HtmlTableCell();
                        cell4.Width = "33%";
                        cell1.Attributes.Add("class", "list-item");
                        cell2.Attributes.Add("class", "list-item");
                        cell3.Attributes.Add("class", "list-item");
                        cell4.Attributes.Add("class", "list-item");
                        row.Cells.Add(cell1);
                        row.Cells.Add(cell2);
                        row.Cells.Add(cell3);
                        row.Cells.Add(cell4);

                        table.Rows.Add(row);
                    }

                    for (int i = 0; i < rowCount; i++)
                    {
                        table.Rows[i].Cells[0].InnerText = fields[2 * i].FieldCaption + ":";
                        table.Rows[i].Cells[1].Controls.Add(GetControl(fields[2 * i], otherContent));
                        if (i != (rowCount - 1) || isOdd)
                        {
                            table.Rows[i].Cells[2].InnerText = fields[2 * i + 1].FieldCaption + ":";
                            table.Rows[i].Cells[3].Controls.Add(GetControl(fields[2 * i + 1], otherContent));
                        }
                    }
                    #endregion
                    break;

                case ShowPlan.OneRowThreeColumn:
                    #region 一行三列
                    rowCount = fields.Count % 3 == 0 ? fields.Count / 3 : fields.Count / 3 + 1;

                    for (int i = 0; i < rowCount; i++)
                    {
                        HtmlTableRow row = new HtmlTableRow();
                        row.Height = "40";
                        HtmlTableCell cell1 = new HtmlTableCell();
                        cell1.Width = "10%";
                        HtmlTableCell cell2 = new HtmlTableCell();
                        cell2.Width = "20%";
                        HtmlTableCell cell3 = new HtmlTableCell();
                        cell3.Width = "10%";
                        HtmlTableCell cell4 = new HtmlTableCell();
                        cell4.Width = "20%";
                        HtmlTableCell cell5 = new HtmlTableCell();
                        cell5.Width = "10%";
                        HtmlTableCell cell6 = new HtmlTableCell();
                        cell6.Width = "20%";

                        cell1.Attributes.Add("class", "list-item");
                        cell2.Attributes.Add("class", "list-item");
                        cell3.Attributes.Add("class", "list-item");
                        cell4.Attributes.Add("class", "list-item");
                        cell5.Attributes.Add("class", "list-item");
                        cell6.Attributes.Add("class", "list-item");

                        row.Cells.Add(cell1);
                        row.Cells.Add(cell2);
                        row.Cells.Add(cell3);
                        row.Cells.Add(cell4);
                        row.Cells.Add(cell5);
                        row.Cells.Add(cell6);

                        table.Rows.Add(row);
                    }

                    for (int i = 0; i < rowCount; i++)
                    {
                        table.Rows[i].Cells[0].InnerText = fields[3 * i].FieldCaption + ":";
                        table.Rows[i].Cells[1].Controls.Add(GetControl(fields[3 * i], otherContent));
                        
                        if ((fields.Count- (3 * i + 1)) == 0)
                            break;
                        table.Rows[i].Cells[2].InnerText = fields[3 * i + 1].FieldCaption + ":";
                        table.Rows[i].Cells[3].Controls.Add(GetControl(fields[3 * i + 1], otherContent));

                        if ((fields.Count-(3 * i + 2)) == 0)
                            break;
                        table.Rows[i].Cells[4].InnerText = fields[3 * i + 2].FieldCaption + ":";
                        table.Rows[i].Cells[5].Controls.Add(GetControl(fields[3 * i + 2], otherContent));
                    }
                    #endregion
                    break;
                case ShowPlan.GroupStyle:
                    #region 分组显示
                    table.Dispose();
                    List<Sagacity.Entity.Build.ResourceFieldGroupInfo> groups = _resource.GetResourceFieldGroupByRId(_resourceInfo.Id);

                    int rownum = 0;
                    foreach (Sagacity.Entity.Build.ResourceFieldGroupInfo g in groups)
                    {
                        FieldSet fieldGroup = GetFieldGroupControls(fields.FindAll(o => o.FieldGroup.Id == g.Id), g.GroupName, otherContent, out rownum);
                        rowCount += rownum;
                        if (fieldGroup != null)
                            container.Add(fieldGroup);
                    }

                    string otherTitle = groups.Count == 0 ? _resourceInfo.ResourceName : "其它信息";

                    FieldSet fieldGroupOther = GetFieldGroupControls(fields.FindAll(o => o.FieldGroup.Id == 0), otherTitle, otherContent, out rownum);
                    if (fieldGroupOther != null)
                        container.Add(fieldGroupOther);
                    rowCount += rownum;
                    #endregion
                    break;
                default:
                    break;
            }

            return rowCount;
        }

        /// <summary>
        /// 字段分组显示
        /// </summary>
        private FieldSet GetFieldGroupControls(List<Sagacity.Entity.Build.QueryFieldInfo> fields,
            string groupName, System.Web.UI.WebControls.Panel otherContent, out int rownum)
        {
            rownum = 0;
            if (fields.Count == 0)
                return null;

            rownum = fields.Count % 2 == 0 ? fields.Count / 2 + 2 : fields.Count / 2 + 3;

            FieldSet fieldGroup = new FieldSet();
            fieldGroup.CheckboxToggle = true;
            fieldGroup.Title = groupName;
            fieldGroup.AutoHeight = true;

            ColumnLayout colunmLayout = new ColumnLayout();
            LayoutColumn column1 = new LayoutColumn();
            column1.ColumnWidth = 0.5m;
            LayoutColumn column2 = new LayoutColumn();
            column2.ColumnWidth = 0.5m;

            Coolite.Ext.Web.Panel panel1 = new Coolite.Ext.Web.Panel();
            panel1.Border = false;
            panel1.Header = false;
            panel1.BodyStyle = "background-color:" + GroupFieldColor;

            Coolite.Ext.Web.Panel panel2 = new Coolite.Ext.Web.Panel();
            panel2.Border = false;
            panel2.Header = false;
            panel2.BodyStyle = "background-color:" + GroupFieldColor;

            FormLayout formLayout1 = new FormLayout();
            formLayout1.LabelAlign = LabelAlign.Left;
            FormLayout formLayout2 = new FormLayout();
            formLayout2.LabelAlign = LabelAlign.Left;

            panel1.BodyContainer.Controls.Add(formLayout1);
            panel2.BodyContainer.Controls.Add(formLayout2);

            column1.Items.Add(panel1);
            column2.Items.Add(panel2);

            colunmLayout.Columns.Add(column1);
            colunmLayout.Columns.Add(column2);

            fieldGroup.BodyContainer.Controls.Add(colunmLayout);

            int counter = 0;
            foreach (Sagacity.Entity.Build.QueryFieldInfo q in fields)
            {
                Anchor anchor = new Anchor();
                anchor.Horizontal = "100%";
                anchor.Items.Add((Coolite.Ext.Web.Component)GetControl(q, otherContent));
                counter++;
                if (counter % 2 != 0)
                    formLayout1.Anchors.Add(anchor);
                else
                    formLayout2.Anchors.Add(anchor);
            }

            return fieldGroup;

        }

        /// <summary>
        /// 根据字段类型添加控件
        /// </summary>
        public Coolite.Ext.Web.WebControl GetControl(Sagacity.Entity.Build.QueryFieldInfo field,
            System.Web.UI.WebControls.Panel otherContent)
        {
            Coolite.Ext.Web.WebControl control = null;
            bool isRowNull = mRow == null;
            bool hasSampleType = false;
            field.FieldControlType = string.IsNullOrEmpty(field.FieldControlType) ? "Label" : field.FieldControlType;

            string rowValue = string.Empty;
            if (mRow != null)
                rowValue = mRow[field.FieldName].ToString();
                //rowValue = mRow[string.IsNullOrEmpty(field.FieldDataSource.Trim()) ? field.FieldName : "CAPTION_" + field.FieldName].ToString();
            else
                rowValue = hasFieldDefault[field.FieldName] == null ? "" : hasFieldDefault[field.FieldName].ToString();

            #region 获取控件

            switch (field.FieldControlType)
            {
                case "Text":
                    Coolite.Ext.Web.TextField txt = new Coolite.Ext.Web.TextField();
                    txt.FieldLabel = field.FieldCaption;
                    txt.Text = rowValue;
                    txt.AllowBlank = field.IsAllowNull;
                    txt.BlankText = blankText;
                    txt.Enabled = field.IsEnableEdit;
                    control = txt;
                    break;
                case "TextArea":
                    Coolite.Ext.Web.TextArea txtArea = new Coolite.Ext.Web.TextArea();
                    txtArea.FieldLabel = field.FieldCaption;
                    txtArea.Text = rowValue;
                    txtArea.AllowBlank = field.IsAllowNull;
                    txtArea.BlankText = blankText;
                    txtArea.Height = 100;
                    txtArea.Enabled = field.IsEnableEdit;
                    control = txtArea;
                    break;
                case "Formula":
                    TriggerField triField = new TriggerField();
                    triField.Text = rowValue;
                    triField.AllowBlank = field.IsAllowNull;
                    triField.BlankText = blankText;
                    triField.Height = 100;
                    triField.Enabled = field.IsEnableEdit;
                    FieldTrigger trigger = new FieldTrigger();
                    trigger.Icon = TemplateTriggerIcon.Search;
                    triField.Triggers.Add(trigger);
                    triField.Listeners.TriggerClick.Handler = "javascript:showFormulaDesigner('"+field.FieldName.ToUpper()+"');";
                    control = triField;
                    break;
                case "DateTime":
                    Coolite.Ext.Web.DateField date = new Coolite.Ext.Web.DateField();
                    date.FieldLabel = field.FieldCaption;
                    date.Format = "yyyy-MM-dd";
                    date.Value = rowValue;
                    date.AllowBlank = field.IsAllowNull;
                    date.BlankText = blankText;
                    date.Disabled = !field.IsEnableEdit;
                    control = date;
                    break;
                 ///填写月份的控件--文本框组合正则表达式
                case "Month":
                    Coolite.Ext.Web.TextField txtMonth = new Coolite.Ext.Web.TextField();
                    txtMonth.FieldLabel = field.FieldCaption;
                    txtMonth.Text = rowValue;
                    txtMonth.AllowBlank = field.IsAllowNull;
                    txtMonth.BlankText = "此值不能为空，请输入正确的月份！";
                    //txtMonth.BlankText = blankText;
                    txtMonth.Regex = @"/^(19|20)\d{2}-(0?\d|1[012])$/";
                    txtMonth.RegexText = "填写的日期格式为：yyyy-MM(年月)";
                    txtMonth.Enabled = field.IsEnableEdit;
                    control = txtMonth;
                    break;
                case "Numeric":
                    Coolite.Ext.Web.NumberField number = new Coolite.Ext.Web.NumberField();
                    number.FieldLabel = field.FieldCaption;
                    number.Text = rowValue;
                    number.AllowBlank = field.IsAllowNull;
                    number.BlankText = blankText;
                    number.Enabled = field.IsEnableEdit;
                    control = number;
                    break;
                case "Button":
                    Coolite.Ext.Web.Button button = new Coolite.Ext.Web.Button();
                    button.Text = field.FieldCaption;
                    button.Listeners.Click.Handler = "Form$ShowUrlTree('" + field.FieldDataSource + "','" + _resourceInfo.ResourceName + " — " + field.FieldCaption + "')";
                    control = button;
                    break;


                #region 针对Combox和Tree数据资源不同
                case "Combox":
                    hasSampleType = true;
                    break;
                case "Tree":
                    hasSampleType = true;
                    break;
                #endregion

                case "Label":
                    Coolite.Ext.Web.Label lbl = new Coolite.Ext.Web.Label();
                    lbl.FieldLabel = field.FieldCaption;
                    lbl.Text = rowValue;
                    control = lbl;
                    break;
                default:
                    break;
            }


            if (field.FieldControlType.ToUpper().IndexOf("SELECTOR") > 0) 
            {
                int type = field.FieldControlType.ToUpper().Trim() == "PERSONSELECTOR" ? 1 : 3;
                Coolite.Ext.Web.TriggerField triggerPSel = new TriggerField();
                triggerPSel.ReadOnly = true;
                triggerPSel.FieldLabel = field.FieldCaption;

                if (!isRowNull)
                    triggerPSel.Text = mRow["CAPTION_"+field.FieldName].ToString();

                triggerPSel.Listeners.TriggerClick.Handler = string.Format("Form$GetSelectorValue({0},\"{1}\")",type,field.FieldName);
                triggerPSel.AllowBlank = field.IsAllowNull;                
                triggerPSel.BlankText = blankText;
                triggerPSel.Enabled = field.IsEnableEdit;
                control = triggerPSel;
            }

            if (hasSampleType == true)
            {
                FieldDatasourceParamInfo fParam = _fieldParams.Find(o => o.Type == 2 && o.Value == field.Id);
                bool hasFieldParam = fParam != null ? true : false;
                FieldDatasourceParamInfo paramter = _fieldParams.Find(o => o.ResourceFieldId == field.Id);
                bool hasAssoedParam = paramter != null && paramter.Type == 2 ? true : false;

                if (paramter != null && paramter.Type != 2)
                {
                    string paramValue = string.Empty;
                    if (paramter.Type == 1)
                    {
                        paramValue = HttpContext.Current.Request.QueryString[paramter.ParamName];
                    }
                    else if (paramter.Type == 3)
                    {
                        paramValue = Sagacity.Build.Sys.SysParameters.HasMainParameters[paramter.ParamName.ToUpper()].ToString();
                    }

                    paramValue = string.IsNullOrEmpty(paramValue) ? "" : paramValue;

                    Sagacity.Entity.Build.QueryFieldInfo f = _resource.GetResourceFieldInfo(field.Id);
                    field.ReplaceFieldParamter(paramter.ParamName, paramValue);
                }
                else if(paramter != null && paramter.Type == 2)
                {
                    field.ReplaceFieldParamter(paramter.ParamName,paramter.OrgValue);
                }

                if (field.FieldControlType.IndexOf("Combox") >= 0)
                {
                    Coolite.Ext.Web.ComboBox combox = new Coolite.Ext.Web.ComboBox();
                    combox.FieldLabel = field.FieldCaption;
                    SetComBoxItems(combox, field);
                    combox.SelectedItem.Value = rowValue.Equals("-1") ? "" : rowValue;
                    
                    if (hasFieldParam)
                    {
                        combox.Listeners.Select.Handler = "javascript:getAssoFieldValues('"+field.FieldName+"');";
                    }
                    
                    combox.Editable = false;
                    combox.AllowBlank = field.IsAllowNull;
                    combox.BlankText = blankText;
                    combox.Enabled = field.IsEnableEdit && !hasAssoedParam;

                    control = combox;
                }
                else if (field.FieldControlType.IndexOf("Tree") >= 0)
                {
                    Coolite.Ext.Web.TriggerField trigger = new TriggerField();
                    trigger.FieldLabel = field.FieldCaption;
                    trigger.ReadOnly = true;
                    trigger.Listeners.TriggerClick.Handler = "javascript:showTreeWin(\"Win_" + field.FieldName + "\");";

                    string contentTitle = string.Empty;
                    otherContent.Controls.Add(setAssociateWin(field, ref contentTitle,false,hasFieldParam));
                    trigger.Text = contentTitle;
                    trigger.AllowBlank = field.IsAllowNull;
                    trigger.BlankText = blankText;
                    trigger.Enabled = field.IsEnableEdit && !hasAssoedParam;
                    control = trigger;
                }
            }

            if (control == null)
                return null;

            if ((control is ComboBox || control is TriggerField) && field.IsAllowNull && field.IsEnableEdit && field.FieldControlType != "Formula")
            {
                FieldTrigger ftrigger = new FieldTrigger();
                ftrigger.Icon = TemplateTriggerIcon.Clear;

                if (control is ComboBox)
                {
                    ComboBox cb = (control as ComboBox);
                    cb.Listeners.TriggerClick.Handler = "triggerValue('" + field.FieldName + "',index)";
                    cb.Triggers.Add(ftrigger);
                }
                else
                {
                    TriggerField tg = control as TriggerField;
                    tg.Listeners.TriggerClick.Handler = string.Format("triggerValue('{0}',index,'{1}')", field.FieldName, tg.Listeners.TriggerClick.Handler);
                    tg.Triggers.Add(ftrigger);

                    FieldTrigger ftriggerTwo = new FieldTrigger();
                    ftriggerTwo.Icon = TemplateTriggerIcon.Ellipsis;
                    tg.Triggers.Add(ftriggerTwo);
                }
            }
            
            control.ID = field.FieldName;
            control.Width = showPlan == ShowPlan.OneRowOneColumn ? field.FieldWidth : 180;

            #endregion

            return control;
        }

        #region 配置表单中的控件

        /// <summary>
        /// 设置下拉框选择项
        /// </summary>
        protected void SetComBoxItems(Coolite.Ext.Web.ComboBox combox, Sagacity.Entity.Build.QueryFieldInfo field)
        {
            DbParameter[] parameters = null;
            
            List<FieldDatasourceParamInfo> fparams = _fieldParams.FindAll(o => o.Type == 2 && o.ResourceFieldId == field.Id);
            if (fparams != null && fparams.Count > 0)
            {
                parameters = new DbParameter[1];
                parameters[0] = new SqlParameter(fparams[0].ParamName, 0);
            }

            DataTable dt = mCommon.GetSQLResult(field.FieldDataSource,parameters);

            hasFieldSource.Add(field.FieldName, dt);
            foreach (DataRow r in dt.Rows)
            {
                Coolite.Ext.Web.ListItem item = new Coolite.Ext.Web.ListItem();
                item.Value = r["Id"].ToString();
                item.Text = r["Caption"].ToString();

                combox.SelectedItem.Value = mRow == null ? "" : mRow[field.FieldName].ToString();

                combox.Items.Add(item);
            }
            combox.DataBind();
        }

        #region 树的处理
        /// <summary>
        /// 为树形控件提供窗体
        /// </summary>
        public Window setAssociateWin(Sagacity.Entity.Build.QueryFieldInfo field, ref string contentTitle, bool isBiz,bool hasFieldParam)
        {
            //搭建Window窗体框架
            Coolite.Ext.Web.Window win = new Window();
            win.ID = "Win_" + field.FieldName;
            win.Title = field.FieldCaption;
            win.Width = 245;
            win.Height = 200;
            win.Modal = true;
            win.AutoHeight = true;
            win.Closable = true;
            win.ShowOnLoad = false;

            //添加树形
            Coolite.Ext.Web.TreePanel tree = new TreePanel();
            tree.ID = "Tree_" + field.FieldName;
            tree.Header = false;
            tree.AutoScroll = true;
            tree.Icon = Icon.Anchor;
            tree.Width = 230;
            tree.Height = 225;
            tree.Lines = false;
            tree.EnableViewState = true;
            tree.Animate = true;

            bool hasParam = _fieldParams.Find(o => o.ResourceFieldId == field.Id && (o.Type == 1 || o.Type == 2 || o.Type == 3)) != null;
            if (!hasParam && isBiz && Sagacity.Build.Sys.SysParameters.HaveMainParameters(field.FieldDataSource))
            {
                hasParam = true;
            }

            string cachekey = string.Empty;
            if (isBiz)
                cachekey = ("Form_FieldData_Biz_" + field.Id).ToUpper();
            else
                cachekey = ("Form_FieldData_" + field.Id).ToUpper();


            DataTable dt = null;
            string fieldName = field.FieldName;

            string nodeClickHandler = "javascript:Form$isDataType(this,'" + fieldName + "')";
            int parentId = 0;
            
            ///默认选中值
            int selectValue = -1;
            if (mRow != null && mRow[fieldName] != null && !string.IsNullOrEmpty(mRow[fieldName].ToString()))
                selectValue = int.Parse(mRow[fieldName].ToString());
            else if (hasFieldDefault[fieldName] != null)
                selectValue = int.Parse(hasFieldDefault[fieldName].ToString());

            if (hasParam)
            {
                field.FieldDataSource = Sagacity.Build.Sys.SysParameters.SetMainParameters(field.FieldDataSource);
                dt = mCommon.GetSQLResult(field.FieldDataSource, null);
                DataRow [] rows = GetTreeRootId(dt);

                Coolite.Ext.Web.TreeNode root = new Coolite.Ext.Web.TreeNode("RootNode");
                tree.RootVisible = rows.Length == 0;

                if (rows.Length > 0)
                    parentId = int.Parse(rows[0]["ParentId"].ToString());
                else
                {
                    parentId = 0;
                    root.Text = "无数据";
                    root.DataType = 0;
                }

                
                GetTreeNodeChild(dt, root.Nodes, parentId, nodeClickHandler);
                GetTreeShowTitle(dt, selectValue, ref contentTitle);

                tree.Root.Add(root);
            }
            else
            {
                CacheManage.RefreshCacheDependencyObject(DataSourceType.FieldSourceData, field.Id);
                dt = (DataTable)CacheManage.GetCacheObject(cachekey);
                if (dt == null)
                {
                    dt = mCommon.GetSQLResult("SELECT t.* FROM (" + field.FieldDataSource + ") t ORDER BY t.parentid", null);
                    CacheManage.AddCacheObject(cachekey, dt,
                         DataSourceType.FieldSourceData, field.Id);

                    //将错误信息记录在日志中
                    //if (dt.Rows.Count == 0)
                        //Business.SysMange.Common.GetSysLog.Warn(string.Format("资源字段 -{0}- 数据源值为空。",field.Id));
                }

                GetTreeShowTitle(dt, selectValue, ref contentTitle);

                AsyncTreeNode asyncNode = new AsyncTreeNode();
                asyncNode.FieldId = field.Id;

                DataRow[] rows = GetTreeRootId(dt);
                if (rows.Length == 0) 
                {
                    asyncNode.Text = "无数据";
                    asyncNode.DataType = 0;
                }
                else if (rows.Length == 1)
                {
                    asyncNode.NodeID = rows[0]["Id"].ToString();
                    asyncNode.Text = rows[0]["Caption"].ToString();

                    //设置树节点的图标
                    object icon = GetTableColumnValue(rows[0], "Icon");
                    asyncNode.IconFile = icon == null ? null : "../resources/images/tree/" + icon.ToString();

                    //指定数据是否是数据节点,默认为“1，数据节点”
                    object dataType = GetTableColumnValue(rows[0], "DataType");
                    asyncNode.DataType = dataType == null ? 1 : int.Parse(dataType.ToString());
                }
                else
                {
                    asyncNode.NodeID = dt.Rows[0]["parentId"].ToString();
                    asyncNode.Text = "请选择—" + field.FieldCaption;
                    asyncNode.DataType = 0;//非数据节点（不可选择）
                }

                asyncNode.Listeners.Click.Handler = nodeClickHandler;
                asyncNode.NodeClickHandler = nodeClickHandler;
                asyncNode.Leaf = false;
                tree.Root.Add(asyncNode);
                tree.Listeners.BeforeLoad.Fn = "Form$nodeLoad";
            }

            hasFieldSource.Add(fieldName, dt);

            win.BodyContainer.Controls.Add(tree);
            win.Resizable = false;


            //为window添加确定，取消按钮,并使用table控制格式
            System.Web.UI.HtmlControls.HtmlTable table = new HtmlTable();
            table.Style.Add("width", "100%");
            System.Web.UI.HtmlControls.HtmlTableRow row = new HtmlTableRow();
            row.Style.Add("width", "100%");

            System.Web.UI.HtmlControls.HtmlTableCell cell1 = new HtmlTableCell();
            cell1.Style.Add("width", "50%");
            cell1.Align = "right";
            System.Web.UI.HtmlControls.HtmlTableCell cell2 = new HtmlTableCell();
            cell2.Style.Add("width", "50%");
            cell2.Align = "left";

            Coolite.Ext.Web.Button btnOK = new Coolite.Ext.Web.Button();
            btnOK.ID = "btn_OK_" + field.FieldName;
            btnOK.Text = "确定";
            btnOK.OnClientClick = "javascript:getTreeSelectValue('" + fieldName + "','" + tree.ID + "','" + win.ID + "','" + field.FieldCaption + "');";
            if (hasFieldParam)
            {
                btnOK.OnClientClick += "getAssoFieldValues('" + fieldName + "');";
            }

            cell1.Controls.Add(btnOK);

            Coolite.Ext.Web.Button btnCancel = new Coolite.Ext.Web.Button(); 
            btnCancel.ID = "btn_Calcel_" + fieldName;
            btnCancel.OnClientClick = "javascript:hideTreeWin('" + win.ID + "');";
            btnCancel.Text = "取消";
            cell2.Controls.Add(btnCancel);

            row.Cells.Add(cell1);
            row.Cells.Add(cell2);
            table.Rows.Add(row);
            win.BodyContainer.Controls.Add(table);
            return win;
        }

        /// <summary>
        /// 查找数据节点类型为2的根节点数据，如果不存在则返回列表中ParentId最小值
        /// 参考：http://app.lexmis.com:8800/jira/browse/LEXMIS-52
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        private DataRow[] GetTreeRootId(DataTable dt) 
        {
            string temp = "";
            if (dt.Columns.Contains("DataType"))
            {
                //数据节点类型为2，表示为根节点
                DataRow[] parentRows = dt.Select("DataType=2");
                if (parentRows.Length > 0)
                {
                    return parentRows;
                }
                else
                {
                    System.Data.DataView dv = new System.Data.DataView(dt);
                    dv.Sort = "ParentId";
                    dt = dv.ToTable();
                    temp = dt.Rows.Count == 0 || dt.Rows[0]["ParentId"] == null ? "0" : dt.Rows[0]["ParentId"].ToString();
                    return dt.Select("ParentId=" + temp);
                }
            }
            else 
            {
                System.Data.DataView dv = new System.Data.DataView(dt);
                dv.Sort = "ParentId";
                dt = dv.ToTable();
                temp = dt.Rows.Count == 0 || string.IsNullOrEmpty(dt.Rows[0]["ParentId"].ToString()) ? "0" : dt.Rows[0]["ParentId"].ToString();
                return dt.Select("ParentId=" + temp);
            }
        }

        /// <summary>
        /// 配合数据源，以递归的方式获得树形结构
        /// </summary>
        protected void GetTreeNodeChild(DataTable dt,
            Coolite.Ext.Web.TreeNodeCollection parentNodes, int parentId, string nodeClickHandler)
        {
            DataRow [] query = dt.Select("ParentId=" + parentId);
            object icon = null;
            object dataType = null;
            foreach (DataRow q in query)
            {
                Coolite.Ext.Web.TreeNode n = new Coolite.Ext.Web.TreeNode();
                n.Text = q["Caption"].ToString();
                n.NodeID = q["Id"].ToString();

                //设置树节点的图标
                icon = GetTableColumnValue(q, "Icon");
                n.IconFile = icon == null ? null : "../resources/images/tree/" + icon.ToString();

                //指定数据是否是数据节点,默认为“1，数据节点”
                dataType = GetTableColumnValue(q, "DataType");
                n.DataType = dataType == null ? 1 : int.Parse(dataType.ToString());
                n.Listeners.Click.Handler = nodeClickHandler;

                GetTreeNodeChild(dt, n.Nodes, int.Parse(q["Id"].ToString()), nodeClickHandler);
                parentNodes.Add(n);
            }
        }

        /// <summary>
        /// 使用Ajax的方式获取树的数据
        /// </summary>
        /// <param name="nodeId">节点编号</param>
        /// <param name="fieldId">所属字段编号</param>
        /// <returns></returns>
        public string NodeLoad(string nodeId, int fieldId,bool isBiz,string nodeClickHandler)
        {
            string cachekey = string.Empty;
            if (isBiz)
                cachekey = ("Form_FieldData_Biz_" + fieldId).ToUpper();
            else
                cachekey = ("Form_FieldData_" + fieldId).ToUpper();

            CacheManage.RefreshCacheDependencyObject(DataSourceType.FieldSourceData, fieldId);
            DataTable data = (DataTable)CacheManage.GetCacheObject(cachekey);

            if (data == null)
            {
                Sagacity.Entity.Build.QueryFieldInfo fieldInfo = (new Sagacity.Build.Application.Resource()).GetResourceFieldInfo(fieldId);
                Sagacity.Entity.Query.FieldDatasourceParamInfo param = _fieldParams.Find(o => o.Type == 3 && o.ResourceFieldId == fieldId);
                if (param != null)
                {
                    fieldInfo.ReplaceFieldParamter(param.ParamName, Sagacity.Build.Sys.SysParameters.HasMainParameters[param.ParamName].ToString());
                }

                data = mCommon.GetSQLResult(fieldInfo.FieldDataSource,null);
                CacheManage.AddCacheObject(cachekey, data,
                     DataSourceType.FieldSourceData, fieldId);
            }

            DataRow[] rowchilds = data.Copy().Select("parentId=" + nodeId);
            Coolite.Ext.Web.TreeNodeCollection nodes = new Coolite.Ext.Web.TreeNodeCollection();

            if (rowchilds != null && rowchilds.Length != 0 && !string.IsNullOrEmpty(nodeId))
            {
                object icon = null;
                object dataType = null;
                foreach (DataRow r in rowchilds)
                {
                    AsyncTreeNode asyncNode = new AsyncTreeNode();
                    asyncNode.Text = r["Caption"].ToString();
                    asyncNode.NodeID = r["Id"].ToString();
                    asyncNode.Leaf = data.Copy().Select("ParentId='" + r["Id"]+"'").Length == 0;
                    
                    asyncNode.FieldId = fieldId;

                    icon = GetTableColumnValue(r, "Icon");
                    asyncNode.IconFile = icon == null ? null : "../resources/images/tree/" + icon.ToString();

                    //指定数据是否是数据节点,默认为“1，数据节点”
                    dataType = GetTableColumnValue(r, "DataType");
                    asyncNode.DataType = dataType == null ? 1 : int.Parse(dataType.ToString());
                    asyncNode.Listeners.Click.Handler = nodeClickHandler;
                    asyncNode.NodeClickHandler = nodeClickHandler;
                    nodes.Add(asyncNode);
                }
            }

            return nodes.ToJson();
        }

        /// <summary>
        /// 获取指定数据行所在的表中是否存在指定的列名，
        /// 如果存在则返回当前行当前列的值，否则返回空
        /// </summary>
        /// <param name="r">数据行</param>
        /// <param name="columnName">列名</param>
        /// <returns></returns>
        public static object GetTableColumnValue(DataRow r, string columnName)
        {
            object obj = null;
            if (r.Table.Columns.Contains(columnName) && !string.IsNullOrEmpty(r[columnName].ToString()))
            {
                obj = r[columnName];
            }
            return obj;
        }

        /// <summary>
        /// 获取树形控件显示的文本
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="Id"></param>
        /// <param name="subtitle"></param>
        public void GetTreeShowTitle(DataTable dt, int Id, ref string subtitle)
        {
            if (Id < 0)
                return;

            DataRow [] rows = dt.Select("Id=" + Id);
            if (rows.Length != 0)
            {
                string temp = string.IsNullOrEmpty(subtitle) ? subtitle : " => ";
                subtitle = rows[0]["Caption"].ToString() + temp + subtitle;
                if (!string.IsNullOrEmpty(rows[0]["ParentId"].ToString()))
                {
                    GetTreeShowTitle(dt, int.Parse(rows[0]["ParentId"].ToString()), ref subtitle);
                }
            }
        }

        #endregion

        #endregion
        #endregion

        /// <summary>
        /// 获取资源字段部分信息--定义当某字段设定为显示但是不能编辑时为不可插入字段
        /// </summary>
        public string GetResourceFieldXML(List<Sagacity.Entity.Build.QueryFieldInfo> fields, string tableKey, DataRow r)
        {
            List<FieldDatasourceParamInfo> fieldParams = null;
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            int rgtProId = 0;
            Sagacity.Build.Query.RightGenerator rgtGener = new Sagacity.Build.Query.RightGenerator();
            builder.Append("<Fields>");
            

            bool rEquilsNull = r != null;
            foreach (Sagacity.Entity.Build.QueryFieldInfo field in fields)
            {
                bool addField = (field.IsEnableEdit || field.FieldName.ToUpper() == tableKey.ToUpper());
                builder.Append("<Field Name='" + field.FieldName + "' ControlType='" + field.FieldControlType + "' IsHidden='" + field.IsHidden.ToString() +
                    "' EnableEdit='" + field.IsEnableEdit.ToString() + "' AddField='" + addField.ToString() + "' Value='");
                
                if (rEquilsNull)
                    builder.Append(r[field.FieldName].ToString());
                
                //设置XML中的字段默认值
                if (!rEquilsNull && hasFieldDefault[field.FieldName] != null)
                    builder.Append(hasFieldDefault[field.FieldName]);

                builder.Append("'");

                if (field.FieldControlType == "Button")
                    builder.Append(" DataSourceUrl='" + field.FieldDataSource + "' WinTitle ='" + _resourceInfo.ResourceName + " — " + field.FieldCaption + "' ");
                
                builder.Append(" FieldStyle='" + field.FieldStyle+"'");

                #region 设置字段数据源关联参数JSON
                string paramList = "[";
                fieldParams = _fieldParams.FindAll(o => o.Type == 2 && o.Value == field.Id);
                foreach (FieldDatasourceParamInfo fp in fieldParams) 
                {
                    Sagacity.Entity.Build.QueryFieldInfo f = fields.Find(o => o.Id == fp.ResourceFieldId);
                    if (f == null)
                        continue;

                    paramList += "{'FieldId':'"+f.Id+"','FieldName':'"+f.FieldName+"','ParamName':'"+fp.ParamName+"'},";
                }
                paramList += "]";
                paramList = paramList.Length > 2 ? paramList.Remove(paramList.LastIndexOf(','),1) : "";

                #endregion

                rgtProId = field.RightProjectInfo.Id;
                if (rgtProId > 0) 
                {
                    Sagacity.Entity.Query.RgtProjectInfo rgtInfo = rgtGener.GetObject<Sagacity.Entity.Query.RgtProjectInfo>(rgtProId);
                    rgtInfo.ModelInfo = rgtGener.GetObject<Sagacity.Entity.Query.ModelInfo>(rgtInfo.ModelInfo.Id);
                    int temp = rgtInfo.ModelInfo.SQL.IndexOf(_resourceInfo.TableName,0,StringComparison.InvariantCultureIgnoreCase);
                    if (temp == -1)
                        rgtProId = 0;
                }
                
                builder.Append(" AssoParam=\""+paramList+"\" RightPro=\""+rgtProId+"\" />");
            }
            builder.Append("</Fields>");
            return builder.ToString();
        }

        /// <summary>
        /// 执行表单信息操作
        /// 在HostFormCommon.ascx中进行的操作只有新增和修改，
        /// 因此没有GridPanel中的删除，此时可以将handleObject设置为空
        /// </summary>
        public bool SaveTableInfo(XmlDocument doc, bool newKey, string handleObject,out string keyId,ref string msg)
        {
            Hashtable has = new Hashtable();

            XmlNode table = doc.SelectSingleNode("Root/TableInfo");
            XmlNode key = doc.SelectSingleNode("Root/Fields/Field[@Name='" + table.Attributes["KeyName"].Value + "']");
            XmlNode ruleFilter = doc.SelectSingleNode("Root/RuleFilter");
            XmlNodeList proDataNodes = doc.SelectNodes("Root/Fields/Field[@RightPro > 0][@AddField='True']");
            List<Sagacity.Entity.Build.RgtQueryProjectDataInfo> proDatas = null;

            #region 生成SQL操作语句
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            //状态为0新增，1修改,2删除
            string excuteState = table.Attributes["CurrentExcuteSate"].Value;
            string allowLog = table.Attributes["Log"].Value;
            string log = null;
            bool excuteResult = false;
            
            switch (excuteState)
            {
                case "0":
                    #region 新增
                    if (newKey)
                        keyId = key.Attributes["Value"].Value = Business.SysMange.Common.GetCounter(table.Attributes["Name"].Value).ToString();

                    
                    XmlNodeList addFields = doc.SelectNodes("Root/Fields/Field[@AddField='True'][@ControlType!='Button']");                    
                    builder.Append("insert into " + table.Attributes["Name"].Value + " (");

                    for (int i = 0; i < addFields.Count; i++)
                    {
                        builder.Append(addFields[i].Attributes["Name"].Value);
                        if (i != (addFields.Count - 1))
                            builder.Append(",");
                    }
                    builder.Append(" ) values ( ");
                    for (int i = 0; i < addFields.Count; i++)
                    {
                        builder.Append(" @" + addFields[i].Attributes["Name"].Value);
                        if (i != (addFields.Count - 1))
                            builder.Append(",");

                        if ((addFields[i].Attributes["ControlType"].Value == "Numeric"
                            || addFields[i].Attributes["ControlType"].Value == "Tree"
                            || addFields[i].Attributes["ControlType"].Value == "Combox"
                            || addFields[i].Attributes["ControlType"].Value == "PersonSelector"
                            || addFields[i].Attributes["ControlType"].Value == "PositionSelector"
                            ) && addFields[i].Attributes["Value"].Value == "")
                            has.Add(addFields[i].Attributes["Name"].Value, "-1");
                        else
                            has.Add(addFields[i].Attributes["Name"].Value, addFields[i].Attributes["Value"].Value);
                    }
                    builder.Append(")");

                    #region 生成日志
                    if (allowLog == "true")
                    {
                        //CFG_LOG主键为自增字段
                        log = string.Format(@"insert into CFG_LOG (RESOURCE_ID,DATA_ID,OPERATORTYPE,OPERATORID,OPERATORDATE)
                        values({0},{1},{2},{3},'{4}')", table.Attributes["Resource"].Value, key.Attributes["Value"].Value,
                                                          table.Attributes["CurrentExcuteSate"].Value, table.Attributes["CurrentUser"].Value, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    }
                    #endregion

                    proDatas = GetRgtProDatas(proDataNodes);

                    excuteResult = Business.SysMange.Common.ExcuteFormCommand(builder.ToString(), has, log,proDatas);
                    #endregion
                    break;
                case "1":
                    #region 修改
                    XmlNodeList editFields = doc.SelectNodes("Root/Fields/Field[@EnableEdit='True'][@ControlType!='Button']");
                    builder.Append("update " + table.Attributes["Name"].Value + " set ");

                    for (int i = 0; i < editFields.Count; i++)
                    {
                        builder.Append(editFields[i].Attributes["Name"].Value + " = " + " @" + editFields[i].Attributes["Name"].Value);
                        if (i != (editFields.Count - 1))
                            builder.Append(",");

                        if ((editFields[i].Attributes["ControlType"].Value == "Numeric"
                            || editFields[i].Attributes["ControlType"].Value == "Tree"
                            || editFields[i].Attributes["ControlType"].Value == "Combox"
                            || editFields[i].Attributes["ControlType"].Value == "PersonSelector"
                            || editFields[i].Attributes["ControlType"].Value == "PositionSelector"
                            ) && editFields[i].Attributes["Value"].Value == "")
                            has.Add(editFields[i].Attributes["Name"].Value, "-1");
                        else
                            has.Add(editFields[i].Attributes["Name"].Value, editFields[i].Attributes["Value"].Value);
                    }
                    builder.Append(" where " + table.Attributes["KeyName"].Value + " = " + key.Attributes["Value"].Value);

                    #region 生成日志

                    if (allowLog == "true")
                    {
                        log = string.Format(@"insert into CFG_LOG (RESOURCE_ID,DATA_ID,OPERATORTYPE,OPERATORID,OPERATORDATE)
                        values({0},{1},{2},{3},'{4}')", table.Attributes["Resource"].Value,
                         key.Attributes["Value"].Value, table.Attributes["CurrentExcuteSate"].Value, table.Attributes["CurrentUser"].Value, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    }
                    #endregion

                    excuteResult = Business.SysMange.Common.ExcuteFormCommand(builder.ToString(), has, log);
                    #endregion
                    break;
                case "2":
                    #region 删除

                    int[] selects = GetSelectRecord(handleObject);
                    Hashtable sql = new Hashtable();
                    Hashtable logs = new Hashtable();
                    foreach (int s in selects)
                    {
                        sql.Add(sql.Count, "delete " + table.Attributes["Name"].Value + " where " + table.Attributes["KeyName"].Value + " = " + s);
                    }

                    if (allowLog == "true")
                    {
                        foreach (int s in selects)
                        {
                            logs.Add(logs.Count, string.Format(@"insert into CFG_LOG (RESOURCE_ID,DATA_ID,OPERATORTYPE,OPERATORID,OPERATORDATE)
                            values({0},{1},{2},{3},'{4}')", table.Attributes["Resource"].Value,
                            s, table.Attributes["CurrentExcuteSate"].Value, table.Attributes["CurrentUser"].Value, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                        }
                    }

                    int ruleDataId = string.IsNullOrEmpty(ruleFilter.Attributes["DataId"].Value) ? 0 : int.Parse(ruleFilter.Attributes["DataId"].Value);
                    int ruleType = string.IsNullOrEmpty(ruleFilter.Attributes["Type"].Value) ? 0 : int.Parse(ruleFilter.Attributes["Type"].Value);

                    proDatas = GetRgtProDatas(proDataNodes);
                    excuteResult = mCommon.ExcuteFormDelCommand(sql, logs, table.Attributes["Resource"].Value, table.Attributes["KeyName"].Value, selects[0], ref msg, table.Attributes["CurrentUser"].Value,ruleDataId,ruleType,proDatas);
                    #endregion
                    break;
                default:
                    break;
            }
            #endregion
            keyId = key.Attributes["Value"].Value;
            return excuteResult;
        }

        /// <summary>
        /// 设置权限数据配置信息
        /// </summary>
        /// <param name="proDatas">有关配置的数据节点集合</param>
        /// <returns>权限配置数据</returns>
        private List<Sagacity.Entity.Build.RgtQueryProjectDataInfo> GetRgtProDatas(XmlNodeList proDataNodes) 
        {
            List<Sagacity.Entity.Build.RgtQueryProjectDataInfo> proDatas = null;

            if (proDataNodes.Count > 0)
                proDatas = new List<Sagacity.Entity.Build.RgtQueryProjectDataInfo>();

            foreach (XmlNode pd in proDataNodes)
            {
                Sagacity.Entity.Build.RgtQueryProjectDataInfo rgtpd = new Sagacity.Entity.Build.RgtQueryProjectDataInfo();
                rgtpd.DataId = int.Parse(pd.Attributes["Value"].Value);
                rgtpd.RightProjectInfo.Id = int.Parse(pd.Attributes["RightPro"].Value);
                rgtpd.RoleID = _currentUser.LoginRole.Id;
                rgtpd.IsGroup = false;
                proDatas.Add(rgtpd);
            }
            return proDatas;
        }

        private int[] GetSelectRecord(string objects)
        {
            string[] selects = objects.Split(new char[] { '$' }, StringSplitOptions.RemoveEmptyEntries);
            int[] checks = new int[selects.Length];
            for (int i = 0; i < selects.Length; i++)
            {
                checks[i] = int.Parse(selects[i]);
            }
            return checks;
        }

        /// <summary>
        /// 执行Sql方案第一类别-自动更新的sql语句执行
        /// </summary>
        /// <param name="resourceId"></param>
        /// <returns>执行是否成功</returns>
        public string ExcuteSqlCase(int [] sqlcaseIds)
        {
            string exMsg = string.Empty;
            List<Sagacity.Entity.Build.SqlCaseInfo> exsqlcaseInfos = _resource.GetSqlCaseInfos(sqlcaseIds);
            if (exsqlcaseInfos.Count == 0) 
            {
                return "系统中未能查询到有效的执行方案！";
            }

            string[] exsqlcases = new string[exsqlcaseInfos.Count];
            for (int i = 0 ;i < exsqlcaseInfos.Count;i++) 
            {
                exsqlcases[i] = exsqlcaseInfos[i].CaseContent;
            }

            mCommon.ExcuteSqlsCommand(exsqlcases,ref exMsg);
            return exMsg;
        }

        /// <summary>
        /// 初始化Sql方案界面
        /// </summary>
        /// <param name="tbSqlCase"></param>
        /// <param name="resourceId"></param>
        /// <param name="win"></param>
        /// <returns></returns>
        public string InitSqlCase(HtmlTable tbSqlCase,int resourceId,Coolite.Ext.Web.Window win,Coolite.Ext.Web.MenuItem menu)
        {
            List<Sagacity.Entity.Build.SqlCaseInfo> sqlcases = _resource.GetSqlCaseInfos(resourceId, 1);
            if (sqlcases.Count == 0)
            {
                win.Visible = false;
                menu.Visible = false;
                return "";
            }

            int rowcount = sqlcases.Count % 5 == 0 ? sqlcases.Count / 5 : sqlcases.Count / 5 + 1;
            for (int i = 0; i < rowcount; i++)
            {
                tbSqlCase.Rows.Add(new HtmlTableRow());
            }

            win.Height = rowcount * 25 + 65;

            rowcount = 0;
            int count = 0;
            string array = string.Empty;

            foreach (Sagacity.Entity.Build.SqlCaseInfo sql in sqlcases)
            {
                HtmlTableCell tableCell = new HtmlTableCell();
                Coolite.Ext.Web.Checkbox ck = new Coolite.Ext.Web.Checkbox();
                ck.BoxLabel = sql.CaseName;
                ck.Checked = false;
                ck.Value = sql.Id;
                ck.ID = "ckSqlCase"+sql.Id;
                ck.Width = 150;
                tableCell.Controls.Add(ck);
                tbSqlCase.Rows[rowcount].Cells.Add(tableCell);
                array += sql.Id + ",";
                count++;

                if (count == 5)
                {
                    rowcount++;
                    count = 0;
                }
            }

            return array.Remove(array.LastIndexOf(','), 1);
        }
    }

    public class CacheManage
    {
        private static Sagacity.Cache.ICache _cache = Sagacity.Cache.CacheProvider.GetInstance;
        /// <summary>
        /// 取得缓存依赖键前缀
        /// </summary>
        /// <param name="dst"></param>
        /// <returns></returns>
        private static string GetDependencyKeyPrefix(DataSourceType dst) 
        {
            switch(dst)
            {
                case DataSourceType.FieldSourceData:
                    return "DependencyKey_FieldSourceData_";
                case DataSourceType.ResourceData:
                    return "DependencyKey_ResourceData_";
                default:
                    return "DependencyKey_Other_";
            }
        }

        /// <summary>
        /// 取得缓存对象
        /// </summary>
        /// <returns></returns>
        public static object GetCacheObject(string cacheKey)
        {
            return _cache.RetrieveObject(cacheKey);
        }

        /// <summary>
        /// 添加缓存对象
        /// </summary>
        /// <param name="key">添加对象的缓存键</param>
        /// <param name="obj">添加到缓存中的对象</param>
        /// <param name="files">依赖键关联文件路径</param>
        /// <param name="keys">缓存对象关联键</param>
        public static void AddCacheObject(string key, object obj,DataSourceType dst, int id) 
        {
            string dpKey = GetDependencyKeyPrefix(dst) + id;
            RefreshCacheDependencyObject(dst, id);

            string[] dependces = new string[] {dpKey };
            _cache.AddObjectWithDepend(key, obj, dependces);
        }

        /// <summary>
        /// 刷新缓存关联键对象，检验是否有依赖键的改变
        /// </summary>
        /// <param name="dst">数据源类型</param>
        /// <param name="id">对应编号</param>
        public static void RefreshCacheDependencyObject(DataSourceType dst ,int id) 
        {
            string dpKey = GetDependencyKeyPrefix(dst) + id;//取得缓存键
            object dpObj = _cache.RetrieveObject(dpKey);

            string updateTime = Business.SysMange.CacheDependencyKey.GetResourceUpdateTime((int)dst, id);

            ///如果不存在缓存关联键或者关联键对应的对象已经不同于当前对象时，
            ///添加或替换原来的关联键对象
            if (dpObj == null || !dpObj.ToString().Equals(updateTime))
            {
                _cache.AddObject(dpKey, updateTime);
            }
        }
    }

    /// <summary>
    /// 数据类型--用于缓存的处理
    /// </summary>
    public enum DataSourceType
    {
        /// <summary>
        /// 字段数据
        /// </summary>
        FieldSourceData = 1,

        /// <summary>
        /// 资源数据源
        /// </summary>
        ResourceData = 2,

        /// <summary>
        /// 其它类型数据源
        /// </summary>
        Other = 3
    }

    /// <summary>
    /// 观察窗类型
    /// </summary>
    public enum ObserveType
    {
        /// <summary>
        /// 未设置
        /// </summary>
        NoSet= 0,
        /// <summary>
        /// 人员观察窗
        /// </summary>
        PersonObserve,
        /// <summary>
        /// 其他观察窗（包括保险福利，统计等）
        /// </summary>
        OthersObserve
    }

    /// <summary>
    /// 操作模式
    /// </summary>
    public enum Operation
    {
        Add = 0,
        Update = 1,
        Delete = 2,

        Execute = 11,//业务单执行提交
        Archive = 12//归档
    }

    /// <summary>
    /// 表单显示方案
    /// </summary>
    public enum ShowPlan
    {
        OneRowTwoColumn = 0,
        OneRowOneColumn = 1,
        OneRowThreeColumn = 3,
        /// <summary>
        /// 分组显示方案
        /// </summary>

        GroupStyle = 2
        //资源样式显示方案
        //ResourceStyle = 3,
    }
}